﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyApplication.Common
{
    public abstract class FusionChartBase
    {
        #region 图表功能
        /// <summary>
        /// 图表主标题
        /// </summary>
        public string Caption { get; set; }

        /// <summary>
        /// 图表副标题
        /// </summary>
        public string SubCaption { get; set; }

        /// <summary>
        /// 是否在图表上显示值
        /// </summary>
        public bool ShowValues { get; set; }

        /// <summary>
        /// 右键菜单是否显示关于
        /// </summary>
        public bool ShowAboutMenuItem { get; set; }

        /// <summary>
        /// 背景颜色
        /// </summary>
        public string BgColor { get; set; }

        /// <summary>
        /// 画布颜色
        /// </summary>
        public string CanvasBgColor { get; set; }

        #endregion

        #region 字体属性
        /// <summary>
        /// 图表里面的字体样式
        /// </summary>
        public string BaseFont { get; set; }

        /// <summary>
        /// 图表里面的字体大小
        /// </summary>
        public int BaseFontSize { get; set; }

        /// <summary>
        /// 图表外面的字体大小
        /// </summary>
        public int OutCnvBaseFontSize { get; set; }
        #endregion

        #region 数字格式
        /// <summary>
        /// 指定小数位的位数，[0-10]    例如：='0' 取整
        /// </summary>
        public int DecimalPrecision { get; set; }

        /// <summary>
        /// 是否格式化数字,默认为1(True),自动的给你的数字加上K（千）或M（百万）；若取0,则不加K或M
        /// </summary>
        public bool FormatNumberScale { get; set; }

        /// <summary>
        /// 数据后缀
        /// </summary>
        public string NumberSuffix { get; set; }

        /// <summary>
        /// 数据前缀
        /// </summary>
        public string NumberPrefix { get; set; }
        #endregion

        #region 导出属性设置
        /// <summary>
        /// 是否将导出图片等按钮出现在图表右键菜单中
        /// </summary>
        public bool ExportShowMenuItem { get; set; }

        /// <summary>
        /// 格式的列表图表将显示在上下文菜单中,,该属性的值应该分开键值对.分隔符字符将要采用的'|'（分字符,该属性值的语法如下：KEY=Value
        /// </summary>
        public string ExportFormats { get; set; }

        /// <summary>
        /// 是否允许导出
        /// </summary>
        public bool ExportEnabled { get; set; }

        /// <summary>
        /// 是否使用客户端导出
        /// </summary>
        public bool ExportAtClient { get; set; }

        /// <summary>
        /// 在服务器导出方面而言,这指的是服务器端输出处理程序;在客户导出方面而言,这指的是DOM的组成部分的FusionCharts的导出是在你的网页嵌入
        /// </summary>
        public string ExportHandler { get; set; }

        /// <summary>
        /// 导出完成后的Javascript回调函数
        /// </summary>
        public string ExportCallback { get; set; }

        /// <summary>
        /// 在服务器端的情况下导出，行动指定是否导出的图像将被发送回客户端的下载，或者是否会在服务器上保存。
        /// </summary>
        public ExportAcionType ExportAction { get; set; }

        /// <summary>
        /// 导出文件的名称，不包括后缀
        /// </summary>
        public string ExportFileName { get; set; }

        #endregion

        #region 导出对话框配置
        /// <summary>
        /// 是否要显示在捕获阶段的出口对话框
        /// </summary>
        public bool ShowExportDialog { get; set; }

        /// <summary>
        /// 该消息被显示在对话框中.
        /// </summary>
        public string ExportDialogMessage { get; set; }

        /// <summary>
        /// 对话框背景颜色，十六进制颜色如：e1f5ff
        /// </summary>
        public string ExportDialogColor { get; set; }

        /// <summary>
        /// 对话框前景颜色。
        /// </summary>
        public string ExportDialogBorderColor { get; set; }

        /// <summary>
        /// 对话框文本的字体颜色.
        /// </summary>
        public string ExportDialogFontColor { get; set; }

        /// <summary>
        /// 对话框进度条的颜色.
        /// </summary>
        public string ExportDialogPBColor { get; set; }
        #endregion

        /// <summary>
        /// 构造函数
        /// </summary>
        public FusionChartBase()
        {
            this.ShowValues = true;
            this.OutCnvBaseFontSize = 14;
            this.BaseFont = "宋体";
            this.BaseFontSize = 14;
            this.DecimalPrecision = 2;
            this.FormatNumberScale = false;
            this.ShowAboutMenuItem = false;
            this.BgColor = "FFFFFF";

            this.ExportShowMenuItem = false;
            this.ExportFormats = "JPG=导出为JPG图片|PNG=导出为PNG图片|PDF=导出为PDF文件";

            this.ExportEnabled = true;
            this.ExportAtClient = false;
            this.ExportAction = ExportAcionType.Download;
            this.ExportFileName = "ReportChart";

            this.ShowExportDialog = true;
            this.ExportDialogMessage = "正在导出,请稍候...";
            this.ExportDialogColor = "e1f5ff";
            this.ExportDialogBorderColor = "0372ab";
            this.ExportDialogFontColor = "0372ab";
            this.ExportDialogPBColor = "0372ab";
        }

        /// <summary>
        /// 转换共同的xml
        /// </summary>
        /// <returns></returns>
        public string XMLHead()
        {
            return string.Format("<graph caption='{0}' subcaption='{1}' showValues='{2}' ShowAboutMenuItem='{3}'" +
                                " outCnvBaseFontSize='{4}' baseFontSize='{5}' baseFont='{6}' decimalPrecision='{7}' formatNumberScale='{8}' " +
                                "bgColor='{9}' canvasBgColor='{10}'",
                                this.Caption, this.SubCaption, Convert.ToInt32(this.ShowValues),
                                Convert.ToInt32(this.ShowAboutMenuItem), this.OutCnvBaseFontSize, this.BaseFontSize, this.BaseFont, this.DecimalPrecision, Convert.ToInt32(this.FormatNumberScale),
                                this.BgColor, this.CanvasBgColor);
        }

        /// <summary>
        /// 图表右键菜单
        /// </summary>
        /// <returns></returns>
        public string XMLMenuContext()
        {
            if (this.ExportShowMenuItem)
            {
                return string.Format("exportShowMenuItem='{0}' exportFormats='{1}' ", Convert.ToInt32(this.ExportShowMenuItem), this.ExportFormats);
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// 图表导出属性xml
        /// </summary>
        /// <returns></returns>
        public string XMLExportHandler()
        {
            if (this.ExportEnabled)
            {
                return string.Format("exportEnabled='{0}' exportAtClient='{1}' exportHandler='{2}' exportAction='{3}' exportCallback='{4}' exportFileName='{5}' ",
                                      Convert.ToInt32(this.ExportEnabled), Convert.ToInt32(this.ExportAtClient), this.ExportHandler,
                                      this.ExportAction, this.ExportCallback, this.ExportFileName);
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// 图表导出框属性
        /// </summary>
        /// <returns></returns>
        public string XMLExportDialog()
        {
            if (this.ShowExportDialog)
            {
                return string.Format("showExportDialog='{0}' exportDialogMessage='{1}'  exportDialogColor ='{2}' exportDialogBorderColor ='{3}' exportDialogFontColor ='{4}' exportDialogPBColor = '{5}' ",
                                     Convert.ToInt32(this.ShowExportDialog), this.ExportDialogMessage, this.ExportDialogColor, this.ExportDialogBorderColor,
                                     this.ExportDialogFontColor, this.ExportDialogPBColor);
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// 数据格式
        /// </summary>
        /// <returns></returns>
        public string XMLNumberFormat()
        {
            StringBuilder xmlnum = new StringBuilder();
            if (this.NumberPrefix != null) { xmlnum.AppendFormat("NumberPrefix='{0}' ", this.NumberPrefix); }
            if (this.NumberSuffix != null) { xmlnum.AppendFormat("NumberSuffix='{0}' ", this.NumberSuffix); }
            return xmlnum.ToString();
        }

        /// <summary>
        /// 通用标题格式
        /// </summary>
        /// <returns></returns>
        public string XMLStyles()
        {
            StringBuilder xmlstyles = new StringBuilder();
            xmlstyles.Append("<styles>");
            xmlstyles.Append("   <definition>");
            xmlstyles.Append("      <style name='CaptionFont' type='font' size='12'/>");
            xmlstyles.Append("   </definition>");
            xmlstyles.Append("   <application>");
            xmlstyles.Append("      <apply toObject='CAPTION' styles='CaptionFont' />");
            xmlstyles.Append("      <apply toObject='SUBCAPTION' styles='CaptionFont' />");
            xmlstyles.Append("   </application>");
            xmlstyles.Append("</styles>");
            return xmlstyles.ToString();
        }

        /// <summary>
        /// 转换成XML数据
        /// </summary>
        /// <returns></returns>
        public abstract string ToXML();

    }

    /// <summary>
    /// 标签显示格式
    /// </summary>
    public enum LabelDisplayType
    {
        WRAP,
        ROTATE,
        Stagger
    }

    /// <summary>
    /// Download-发送回客户端的下载，Save-会在服务器上保存。
    /// </summary>
    public enum ExportAcionType
    {
        Save,
        Download
    }

    /// <summary>
    /// 单系类图表数据节点
    /// </summary>
    public class SSDataSet
    {
        /// <summary>
        /// 数据值
        /// </summary>
        public string Value { get; set; }

        /// <summary>
        /// 颜色
        /// </summary>
        public string Color { get; set; }

        /// <summary> 
        /// 链接
        /// </summary>
        public string Link { get; set; }

        /// <summary>
        /// 标签名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 自定义显示的值
        /// </summary>
        public string ToolText { get; set; }

        /// <summary>
        /// 设置在是否显示图表中相对应的柱行图的name
        /// </summary>
        public bool ShowName { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public SSDataSet()
        {
            this.ShowName = true;
        }
    }

    /// <summary>
    /// XY散点图标签节点
    /// </summary>
    public class XYCateGory
    {
        /// <summary>
        /// X轴显示值
        /// </summary>
        public string Label { get; set; }

        /// <summary>
        /// X轴的值
        /// </summary>
        public float X { get; set; }

        /// <summary>
        /// 是否显示网格线
        /// </summary>
        public bool ShowVerticalLine { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public XYCateGory()
        {
            this.ShowVerticalLine = true;
        }
    }

    /// <summary>
    /// 散点图Set节点
    /// </summary>
    public class XYPlotSet
    {
        /// <summary>
        /// 横坐标
        /// </summary>
        public string X { get; set; }

        /// <summary>
        /// 纵坐标
        /// </summary>
        public string Y { get; set; }

        /// <summary>
        /// 鼠标移动上去的值
        /// </summary>
        public string ToolText { get; set; }
    }

    /// <summary>
    /// 2D折线数据节点
    /// </summary>
    public class Line2DSet : SSDataSet
    {
        /// <summary>
        /// 点边数3-20
        /// </summary>
        public int AnchorSides { get; set; }

        /// <summary>
        /// 点半径,像素
        /// </summary>
        public int AnchorRadius { get; set; }

        /// <summary>
        /// 点背景颜色
        /// </summary>
        public string AnchorBgColor { get; set; }

        /// <summary>
        /// 点边框颜色
        /// </summary>
        public string AnchorBorderColor { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public Line2DSet()
        {
            this.AnchorSides = 20;
            this.AnchorRadius = 4;
            this.AnchorBgColor = "D5FFD5";
            this.AnchorBorderColor = "009900";
        }
    }

    /// <summary>
    /// 多系列图表子图节点
    /// </summary>
    public class MSDataSet
    {
        /// <summary>
        /// 子图表标题
        /// </summary>
        public string SeriesName { set; get; }

        /// <summary>
        /// 子图表数据
        /// </summary>
        public List<SSDataSet> SetList { get; set; }

    }

    /// <summary>
    ///  组合图子图节点
    /// </summary>
    public class CombiDataSet
    {
        /// <summary>
        /// 子图表标题
        /// </summary>
        public string SeriesName { set; get; }

        /// <summary>
        /// 以何种图形显示
        /// </summary>
        public string RenderAs { get; set; }

        /// <summary>
        /// 属于哪个轴,P代表主轴，S代表次轴
        /// </summary>
        public string ParentYAxis { get; set; }
        /// <summary>
        /// 子图表数据
        /// </summary>
        public List<SSDataSet> SetList { get; set; }
    }

    /// <summary>
    /// XY散列图子图节点
    /// </summary>
    public class XYPlotDataSet
    {
        /// <summary>
        /// 标题
        /// </summary>
        public string SeriesName { get; set; }

        /// <summary>
        /// 散点边数3-20
        /// </summary>
        public int AnchorSides { get; set; }

        /// <summary>
        /// 散点半径,像素
        /// </summary>
        public int AnchorRadius { get; set; }

        /// <summary>
        /// 散点背景颜色
        /// </summary>
        public string AnchorBgColor { get; set; }

        /// <summary>
        /// 散点边框颜色
        /// </summary>
        public string AnchorBorderColor { get; set; }

        /// <summary>
        /// 散列图子表数据集合
        /// </summary>
        public List<XYPlotSet> SetList { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public XYPlotDataSet()
        {
            this.AnchorSides = 20;
            this.AnchorRadius = 4;
            this.AnchorBgColor = "D5FFD5";
            this.AnchorBorderColor = "009900";
        }
    }

    /// <summary>
    /// 2D柱状图
    /// </summary>
    public class Column2DChart : FusionChartBase
    {
        /// <summary>
        /// 横向坐标轴(x轴)名称
        /// </summary>
        public string XAxisName { get; set; }

        /// <summary>
        /// 纵向坐标轴(y轴)名称
        /// </summary>
        public string YAxisName { get; set; }

        /// <summary>
        /// Y轴最大值
        /// </summary>
        public string YAxisMaxValue { get; set; }

        /// <summary>
        /// Y轴名称是否旋转的显示
        /// </summary>
        public bool RotateYAxisName { get; set; }

        /// <summary>
        /// X轴标签显示格式 WRAP（重叠）ROTATE（旋转）Stagger（交错）
        /// </summary>
        public LabelDisplayType LabelDisplay { get; set; }

        /// <summary>
        /// 标签旋转.1表示倾斜、0表示垂直
        /// </summary>
        public int SlantLabels { get; set; }

        /// <summary>
        /// 对于柱状图是否使用圆角
        /// </summary>
        public bool UseRoundEdges { get; set; }

        /// <summary>
        /// X轴标签步长
        /// </summary>
        public int labelStep { get; set; }

        /// <summary>
        /// 图表数据集合
        /// </summary>
        public List<SSDataSet> SetList { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public Column2DChart()
        {
            this.UseRoundEdges = true;
        }

        public override string ToXML()
        {
            StringBuilder xmlData = new StringBuilder();
            xmlData.Append(this.XMLHead());
            //X轴坐标是否旋转
            if (this.LabelDisplay == LabelDisplayType.ROTATE)
            {
                xmlData.AppendFormat("labelDisplay='{0}' slantLabels='{1}' ", this.LabelDisplay, this.SlantLabels);
            }
            if (labelStep != 0)
            {
                xmlData.AppendFormat("labelStep='{0}'", this.labelStep);
            }
            xmlData.AppendFormat("rotateYAxisName='{0}' ", Convert.ToInt32(this.RotateYAxisName));
            if (this.XAxisName != "") { xmlData.AppendFormat("xAxisName='{0}' ", this.XAxisName); }
            if (this.YAxisName != "") { xmlData.AppendFormat("yAxisName='{0}' ", this.YAxisName); }
            if (this.YAxisMaxValue != null) { xmlData.AppendFormat("yAxisMaxValue='{0}' ", this.YAxisMaxValue); }
            if (this.UseRoundEdges) { xmlData.AppendFormat("useRoundEdges='{0}' ", Convert.ToInt32(this.UseRoundEdges)); }
            xmlData.Append(this.XMLNumberFormat());
            xmlData.Append(this.XMLMenuContext());
            xmlData.Append(this.XMLExportDialog());
            xmlData.Append(this.XMLExportHandler());
            xmlData.Append(">");
            foreach (SSDataSet item in this.SetList)
            {
                xmlData.AppendFormat("<set name='{0}' value='{1}' tooltext='{2}' link=\"{3}\"/>", item.Name, item.Value, item.ToolText, item.Link);
            }
            xmlData.Append(this.XMLStyles());
            xmlData.Append("</graph>");
            return xmlData.ToString();
        }
    }

    /// <summary>
    /// 3D柱状图
    /// </summary>
    public class Column3DChart : FusionChartBase
    {
        /// <summary>
        /// 横向坐标轴(x轴)名称
        /// </summary>
        public string XAxisName { get; set; }

        /// <summary>
        /// 纵向坐标轴(y轴)名称
        /// </summary>
        public string YAxisName { get; set; }

        /// <summary>
        /// Y轴最大值
        /// </summary>
        public string YAxisMaxValue { get; set; }

        /// <summary>
        /// Y轴名称是否旋转的显示
        /// </summary>
        public bool RotateYAxisName { get; set; }

        /// <summary>
        /// X轴标签显示格式 WRAP（重叠）ROTATE（旋转）Stagger（交错）
        /// </summary>
        public LabelDisplayType LabelDisplay { get; set; }

        /// <summary>
        /// 标签旋转.1表示倾斜、0表示垂直
        /// </summary>
        public int SlantLabels { get; set; }

        /// <summary>
        /// X轴标签步长
        /// </summary>
        public int labelStep { get; set; }

        /// <summary>
        /// 图表数据集合
        /// </summary>
        public List<SSDataSet> SetList { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public Column3DChart()
        {
        }

        public override string ToXML()
        {
            StringBuilder xmlData = new StringBuilder();
            xmlData.Append(this.XMLHead());
            //X轴坐标是否旋转
            if (this.LabelDisplay == LabelDisplayType.ROTATE)
            {
                xmlData.AppendFormat("labelDisplay='{0}' slantLabels='{1}' ", this.LabelDisplay, this.SlantLabels);
            }
            if (labelStep != 0)
            {
                xmlData.AppendFormat("labelStep='{0}'", this.labelStep);
            }
            xmlData.AppendFormat("rotateYAxisName='{0}' ", Convert.ToInt32(this.RotateYAxisName));
            if (this.XAxisName != "") { xmlData.AppendFormat("xAxisName='{0}' ", this.XAxisName); }
            if (this.YAxisName != "") { xmlData.AppendFormat("yAxisName='{0}' ", this.YAxisName); }
            if (this.YAxisMaxValue != null) { xmlData.AppendFormat("yAxisMaxValue='{0}' ", this.YAxisMaxValue); }
            xmlData.Append(this.XMLNumberFormat());
            xmlData.Append(this.XMLMenuContext());
            xmlData.Append(this.XMLExportDialog());
            xmlData.Append(this.XMLExportHandler());
            xmlData.Append(">");
            foreach (SSDataSet item in this.SetList)
            {
                xmlData.AppendFormat("<set name='{0}' value='{1}' tooltext='{2}' link=\"{3}\"/>", item.Name, item.Value, item.ToolText, item.Link);

            }
            xmlData.Append(this.XMLStyles());
            xmlData.Append("</graph>");
            return xmlData.ToString();
        }
    }

    /// <summary>
    /// 2D柱状多系列图
    /// </summary>
    public class MSColumn2DChart : FusionChartBase
    {
        /// <summary>
        /// 横向坐标轴(x轴)名称
        /// </summary>
        public string XAxisName { get; set; }

        /// <summary>
        /// 纵向坐标轴(y轴)名称
        /// </summary>
        public string YAxisName { get; set; }

        /// <summary>
        /// Y轴最大值
        /// </summary>
        public string YAxisMaxValue { get; set; }

        /// <summary>
        /// Y轴名称是否旋转的显示
        /// </summary>
        public bool RotateYAxisName { get; set; }

        /// <summary>
        /// X轴标签显示格式 WRAP（重叠）ROTATE（旋转）Stagger（交错）
        /// </summary>
        public LabelDisplayType LabelDisplay { get; set; }

        /// <summary>
        /// 横向坐标轴(x轴)上名称的集合
        /// </summary>
        public List<string> Categories { get; set; }

        /// <summary>
        /// 标签旋转.1表示倾斜、0表示垂直
        /// </summary>
        public int SlantLabels { get; set; }

        /// <summary>
        /// 对于柱状图是否使用圆角
        /// </summary>
        public bool UseRoundEdges { get; set; }

        /// <summary>
        /// 图表数据集合
        /// </summary>
        public List<MSDataSet> DataSetList { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public MSColumn2DChart()
        {
            this.UseRoundEdges = true;
        }

        /// <summary>
        /// 转换XML
        /// </summary>
        /// <returns></returns>
        public override string ToXML()
        {
            StringBuilder xmlData = new StringBuilder();
            xmlData.Append(this.XMLHead());
            //X轴坐标是否旋转
            if (this.LabelDisplay == LabelDisplayType.ROTATE)
            {
                xmlData.AppendFormat("labelDisplay='{0}' slantLabels='{1}' ", this.LabelDisplay, this.SlantLabels);
            }
            xmlData.AppendFormat("rotateYAxisName='{0}' ", Convert.ToInt32(this.RotateYAxisName));
            if (this.XAxisName != "") { xmlData.AppendFormat("xAxisName='{0}' ", this.XAxisName); }
            if (this.YAxisName != "") { xmlData.AppendFormat("yAxisName='{0}' ", this.YAxisName); }
            if (this.YAxisMaxValue != null) { xmlData.AppendFormat("yAxisMaxValue='{0}' ", this.YAxisMaxValue); }
            if (this.UseRoundEdges) { xmlData.AppendFormat("useRoundEdges='{0}' ", Convert.ToInt32(this.UseRoundEdges)); }
            xmlData.Append(this.XMLNumberFormat());
            xmlData.Append(this.XMLMenuContext());
            xmlData.Append(this.XMLExportDialog());
            xmlData.Append(this.XMLExportHandler());
            xmlData.Append(">");
            xmlData.Append("<categories>");
            foreach (string item in this.Categories)
            {
                xmlData.AppendFormat("<category label='{0}' />", item);
            }
            xmlData.Append("</categories>");
            foreach (MSDataSet item in this.DataSetList)
            {
                xmlData.AppendFormat("<dataset seriesName='{0}'>", item.SeriesName);
                foreach (SSDataSet setdate in item.SetList)
                {
                    xmlData.AppendFormat("<set value='{0}' tooltext='{1}' link=\"{2}\"/>", setdate.Value, setdate.ToolText, setdate.Link);
                }
                xmlData.Append("</dataset>");
            }
            xmlData.Append(this.XMLStyles());
            xmlData.Append("</graph>");
            return xmlData.ToString();
        }
    }

    /// <summary>
    /// 双Y轴2D组合图
    /// </summary>
    public class MSCombiDY2DChart : FusionChartBase
    {
        /// <summary>
        /// 横向坐标轴(x轴)名称
        /// </summary>
        public string XAxisName { get; set; }

        /// <summary>
        /// 主Y轴名称
        /// </summary>
        public string PYAxisName { get; set; }

        /// <summary>
        /// 次Y轴名称
        /// </summary>
        public string SYAxisName { get; set; }

        /// <summary>
        /// 次Y轴数据后缀
        /// </summary>
        public string SNumberSuffix { get; set; }

        /// <summary>
        /// 次Y轴数据前缀
        /// </summary>
        public string SNumberPrefix { get; set; }

        /// <summary>
        /// 横向坐标轴(x轴)上名称的集合
        /// </summary>
        public List<string> Categories { get; set; }

        /// <summary>
        /// Y轴名称是否旋转的显示
        /// </summary>
        public bool RotateYAxisName { get; set; }

        /// <summary>
        /// X轴标签显示格式 WRAP（重叠）ROTATE（旋转）Stagger（交错）
        /// </summary>
        public LabelDisplayType LabelDisplay { get; set; }

        /// <summary>
        /// 标签旋转.1表示倾斜、0表示垂直
        /// </summary>
        public int SlantLabels { get; set; }

        /// <summary>
        /// 对于柱状图是否使用圆角
        /// </summary>
        public bool UseRoundEdges { get; set; }

        /// <summary>
        /// 图表数据集合
        /// </summary>
        public List<CombiDataSet> DataSetList { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public MSCombiDY2DChart()
        {
            this.UseRoundEdges = true;
        }

        /// <summary>
        /// 转换XML
        /// </summary>
        /// <returns></returns>
        public override string ToXML()
        {
            StringBuilder xmlData = new StringBuilder();
            xmlData.Append(this.XMLHead());
            //X轴坐标是否旋转
            if (this.LabelDisplay == LabelDisplayType.ROTATE)
            {
                xmlData.AppendFormat("labelDisplay='{0}' slantLabels='{1}' ", this.LabelDisplay, this.SlantLabels);
            }
            xmlData.AppendFormat("rotateYAxisName='{0}' ", Convert.ToInt32(this.RotateYAxisName));
            if (this.XAxisName != "") { xmlData.AppendFormat("xAxisName='{0}' ", this.XAxisName); }
            if (this.PYAxisName != null) { xmlData.AppendFormat("PYAxisName='{0}' ", this.PYAxisName); }
            if (this.SYAxisName != null) { xmlData.AppendFormat("SYAxisName='{0}' ", this.SYAxisName); }
            if (this.SNumberPrefix != null) { xmlData.AppendFormat("SNumberPrefix='{0}' ", this.SNumberPrefix); }
            if (this.SNumberSuffix != null) { xmlData.AppendFormat("SNumberSuffix='{0}' ", this.SNumberSuffix); }
            if (this.UseRoundEdges) { xmlData.AppendFormat("useRoundEdges='{0}' ", Convert.ToInt32(this.UseRoundEdges)); }
            xmlData.Append(this.XMLNumberFormat());
            xmlData.Append(this.XMLMenuContext());
            xmlData.Append(this.XMLExportDialog());
            xmlData.Append(this.XMLExportHandler());
            xmlData.Append(">");
            xmlData.Append("<categories>");
            foreach (string item in this.Categories)
            {
                xmlData.AppendFormat("<category label='{0}' />", item);
            }
            xmlData.Append("</categories>");
            foreach (CombiDataSet item in this.DataSetList)
            {
                xmlData.AppendFormat("<dataset seriesName='{0}' renderAs='{1}' parentYAxis='{2}'>", item.SeriesName, item.RenderAs, item.ParentYAxis);
                foreach (SSDataSet setdate in item.SetList)
                {
                    xmlData.AppendFormat("<set value='{0}' tooltext='{1}' link=\"{2}\"/>", setdate.Value, setdate.ToolText, setdate.Link);
                }
                xmlData.Append("</dataset>");
            }
            xmlData.Append(this.XMLStyles());
            xmlData.Append("</graph>");
            return xmlData.ToString();
        }
    }

    /// <summary>
    /// XY散列图
    /// </summary>
    public class XYPlotChart : FusionChartBase
    {
        /// <summary>
        /// 横向坐标轴(x轴)名称
        /// </summary>
        public string XAxisName { get; set; }

        /// <summary>
        /// 纵向坐标轴(y轴)名称
        /// </summary>
        public string YAxisName { get; set; }

        /// <summary>
        /// X轴最大值
        /// </summary>
        public string XAxisMaxValue { get; set; }

        /// <summary>
        /// Y轴最大值
        /// </summary>
        public string YAxisMaxValue { get; set; }

        /// <summary>
        /// Y轴名称是否旋转的显示
        /// </summary>
        public bool RotateYAxisName { get; set; }

        /// <summary>
        /// X轴标签显示格式 WRAP（重叠）ROTATE（旋转）Stagger（交错）
        /// </summary>
        public LabelDisplayType LabelDisplay { get; set; }

        /// <summary>
        /// 标签旋转.1表示倾斜、0表示垂直
        /// </summary>
        public int SlantLabels { get; set; }

        /// <summary>
        /// 标签集合
        /// </summary>
        public List<XYCateGory> Categories { get; set; }

        /// <summary>
        /// 子图数据集合
        /// </summary>
        public List<XYPlotDataSet> DataSetList { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public XYPlotChart()
        {

        }

        /// <summary>
        /// 转换XML
        /// </summary>
        /// <returns></returns>
        public override string ToXML()
        {
            StringBuilder xmlData = new StringBuilder();
            xmlData.Append(this.XMLHead());
            //X轴坐标是否旋转
            if (this.LabelDisplay == LabelDisplayType.ROTATE)
            {
                xmlData.AppendFormat("labelDisplay='{0}' slantLabels='{1}' ", this.LabelDisplay, this.SlantLabels);
            }
            xmlData.AppendFormat("rotateYAxisName='{0}' ", Convert.ToInt32(this.RotateYAxisName));
            if (this.XAxisName != "") { xmlData.AppendFormat("xAxisName='{0}' ", this.XAxisName); }
            if (this.YAxisName != null) { xmlData.AppendFormat("yAxisName='{0}' ", this.YAxisName); }
            if (this.XAxisMaxValue != null) { xmlData.AppendFormat("xAxisMaxValue ='{0}' ", this.XAxisMaxValue); }
            if (this.YAxisMaxValue != null) { xmlData.AppendFormat("yAxisMaxValue ='{0}' ", this.YAxisMaxValue); }
            //xmlData.Append(this.XMLNumberFormat());
            xmlData.Append(this.XMLMenuContext());
            xmlData.Append(this.XMLExportDialog());
            xmlData.Append(this.XMLExportHandler());
            xmlData.Append(">");
            xmlData.Append("<categories>");
            foreach (var item in this.Categories)
            {
                xmlData.AppendFormat("<category label='{0}' x='{1}' showVerticalLine='{2}'/>", item.Label, item.X, Convert.ToInt32(item.ShowVerticalLine));
            }
            xmlData.Append("</categories>");
            foreach (XYPlotDataSet item in this.DataSetList)
            {
                xmlData.AppendFormat("<dataset seriesName='{0}' anchorSides='{1}' anchorRadius='{2}' anchorBgColor='{3}' anchorBorderColor='{4}'>", item.SeriesName, item.AnchorSides, item.AnchorRadius, item.AnchorBgColor, item.AnchorBorderColor);
                foreach (XYPlotSet set in item.SetList)
                {

                    xmlData.AppendFormat("<set x='{0}' y='{1}' tooltext='{2}'/>", set.X, set.Y, set.ToolText);
                }
                xmlData.Append("</dataset>");
            }
            xmlData.Append(this.XMLStyles());
            xmlData.Append("</graph>");
            return xmlData.ToString();
        }
    }

    /// <summary>
    /// 3D饼图
    /// </summary>
    public class Pie3DChart : FusionChartBase
    {
        /// <summary>
        /// 图表数据集合
        /// </summary>
        public List<SSDataSet> SetList { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public Pie3DChart()
        {

        }

        public override string ToXML()
        {
            StringBuilder xmlData = new StringBuilder();
            xmlData.Append(this.XMLHead());
            xmlData.Append(this.XMLNumberFormat());
            xmlData.Append(this.XMLMenuContext());
            xmlData.Append(this.XMLExportDialog());
            xmlData.Append(this.XMLExportHandler());
            xmlData.Append(">");
            foreach (SSDataSet item in this.SetList)
            {
                xmlData.AppendFormat("<set name='{0}' value='{1}' tooltext='{2}' link=\"{3}\"/>", item.Name, item.Value, item.ToolText, item.Link);
            }
            xmlData.Append(this.XMLStyles());
            xmlData.Append("</graph>");
            return xmlData.ToString();
        }
    }

    /// <summary>
    /// 2D折线图
    /// </summary>
    public class Line2DChart : FusionChartBase
    {
        /// <summary>
        /// 横向坐标轴(x轴)名称
        /// </summary>
        public string XAxisName { get; set; }

        /// <summary>
        /// 纵向坐标轴(y轴)名称
        /// </summary>
        public string YAxisName { get; set; }

        /// <summary>
        /// X轴最大值
        /// </summary>
        public string XAxisMaxValue { get; set; }

        /// <summary>
        /// Y轴最大值
        /// </summary>
        public string YAxisMaxValue { get; set; }

        /// <summary>
        /// Y轴名称是否旋转的显示
        /// </summary>
        public bool RotateYAxisName { get; set; }

        /// <summary>
        /// X轴标签显示格式 WRAP（重叠）ROTATE（旋转）Stagger（交错）
        /// </summary>
        public LabelDisplayType LabelDisplay { get; set; }

        /// <summary>
        /// 折线颜色
        /// </summary>
        public string LineColor { get; set; }

        /// <summary>
        /// 折现粗细
        /// </summary>
        public int LineThickness { get; set; }

        /// <summary>
        /// 标签旋转.1表示倾斜、0表示垂直
        /// </summary>
        public int SlantLabels { get; set; }

        /// <summary>
        /// 子图数据集合
        /// </summary>
        public List<Line2DSet> SetList { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        public Line2DChart()
        {

        }

        /// <summary>
        /// 转换XML
        /// </summary>
        /// <returns></returns>
        public override string ToXML()
        {
            StringBuilder xmlData = new StringBuilder();
            xmlData.Append(this.XMLHead());
            //X轴坐标是否旋转
            if (this.LabelDisplay == LabelDisplayType.ROTATE)
            {
                xmlData.AppendFormat("labelDisplay='{0}' slantLabels='{1}' ", this.LabelDisplay, this.SlantLabels);
            }
            xmlData.AppendFormat("rotateYAxisName='{0}' ", Convert.ToInt32(this.RotateYAxisName));
            if (this.XAxisName != "") { xmlData.AppendFormat("xAxisName='{0}' ", this.XAxisName); }
            if (this.YAxisName != "") { xmlData.AppendFormat("yAxisName='{0}' ", this.YAxisName); }
            if (this.YAxisMaxValue != null) { xmlData.AppendFormat("yAxisMaxValue='{0}' ", this.YAxisMaxValue); }
            if (!string.IsNullOrWhiteSpace(this.LineColor)) { xmlData.AppendFormat("lineColor='{0}' ", this.LineColor); }
            if (this.LineThickness != null) { xmlData.AppendFormat("lineThickness ='{0}' ", this.LineThickness); }
            xmlData.Append(this.XMLNumberFormat());
            xmlData.Append(this.XMLMenuContext());
            xmlData.Append(this.XMLExportDialog());
            xmlData.Append(this.XMLExportHandler());
            xmlData.Append(">");
            foreach (Line2DSet item in this.SetList)
            {
                xmlData.Append("<set ");
                if (!string.IsNullOrWhiteSpace(item.Name)) { xmlData.AppendFormat("name='{0}' ", item.Name); }
                if (!string.IsNullOrWhiteSpace(item.ToolText)) { xmlData.AppendFormat("tooltext='{0}' ", item.ToolText); }
                if (!string.IsNullOrWhiteSpace(item.Link)) { xmlData.AppendFormat("link=\"{0}\" ", item.Link); }
                if (!string.IsNullOrWhiteSpace(item.Value))
                {
                    xmlData.AppendFormat("value='{0}' anchorSides='{1}' anchorRadius='{2}' anchorBgColor='{3}' anchorBorderColor='{4}'", item.Value, item.AnchorSides, item.AnchorRadius, item.AnchorBgColor, item.AnchorBorderColor);

                }
                xmlData.Append("/>");
            }
            xmlData.Append(this.XMLStyles());
            xmlData.Append("</graph>");
            return xmlData.ToString();
        }
    }

}
